Skip to content

Normalize .yml to .yaml in modelopt_recipes#1260

Merged
shengliangxu merged 4 commits intomainfrom
shengliangx/normalize-yaml-ext
Apr 15, 2026
Merged

Normalize .yml to .yaml in modelopt_recipes#1260
shengliangxu merged 4 commits intomainfrom
shengliangx/normalize-yaml-ext

Conversation

@shengliangxu
Copy link
Copy Markdown
Collaborator

@shengliangxu shengliangxu commented Apr 14, 2026

What does this PR do?

Type of change: Chore

Standardize YAML file extensions in modelopt_recipes/ to .yaml for
consistency. The existing recipes used a mix of .yml (PTQ recipes) and
.yaml (speculative decoding, model-specific recipes).

Changes

Renamed files:

  • modelopt_recipes/general/ptq/fp8_default-fp8_kv.yml.yaml
  • modelopt_recipes/general/ptq/nvfp4_default-fp8_kv.yml.yaml
  • modelopt_recipes/general/ptq/nvfp4_experts_only-fp8_kv.yml.yaml
  • modelopt_recipes/general/ptq/nvfp4_mlp_only-fp8_kv.yml.yaml
  • modelopt_recipes/general/ptq/nvfp4_omlp_only-fp8_kv.yml.yaml

New pre-commit hook: normalize-yaml-ext

  • tools/precommit/normalize_yaml_ext.py — auto-renames .yml to .yaml
    for any staged file under modelopt_recipes/. Runs before recipe
    validation so future contributions are caught automatically.

Updated references:

  • tests/unit/recipe/test_loader.py — built-in recipe paths updated to
    .yaml

Note: load_recipe() and load_config() probe both .yml and .yaml
suffixes, so callers using paths without extensions (e.g.,
load_recipe("general/ptq/fp8_default-fp8_kv")) are unaffected.

Testing

Existing recipe loader tests pass with updated paths.

Summary by CodeRabbit

  • Chores
    • Standardized recipe file extensions and added an automated pre-commit normalization hook to enforce the convention.
  • Tests
    • Updated unit tests to reference the new recipe filename convention and ensure consistency with configuration loading.

@shengliangxu shengliangxu requested review from a team as code owners April 14, 2026 18:05
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 14, 2026

📝 Walkthrough

Walkthrough

Adds a new local pre-commit hook and script to normalize .yml.yaml for files under modelopt_recipes/, and updates unit tests to reference .yaml filenames.

Changes

Cohort / File(s) Summary
Pre-commit config
\.pre-commit-config.yaml
Added a local hook entry normalize-yaml-ext that runs python tools/precommit/normalize_yaml_ext.py (language: system) for paths matching ^modelopt_recipes/.*\.yml$.
Pre-commit script
tools/precommit/normalize_yaml_ext.py
New script added. Scans provided paths, renames existing .yml files to .yaml; prints per-file renames. If a target .yaml already exists, reports collisions and exits 1 without performing the conflicting renames. Returns 0 when nothing to rename; exits 1 after successful renames to require re-staging.
Unit tests updated
tests/unit/recipe/test_loader.py
Updated test literals, parameters, and docstrings to use .yaml filenames instead of .yml for built-in PTQ recipe loading and related comparisons.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: normalizing YAML file extensions from .yml to .yaml in the modelopt_recipes directory, which is the core objective of this PR.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Security Anti-Patterns ✅ Passed The pull request introduces no new security anti-patterns. The new normalize_yaml_ext.py script performs only safe file operations using standard library functions without dangerous deserialization, code execution, or remote code trust settings.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch shengliangx/normalize-yaml-ext

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 14, 2026

PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-04-15 00:51 UTC

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tools/precommit/normalize_yaml_ext.py`:
- Around line 35-38: The rename currently does not guard against destination
collisions and may silently overwrite existing files (os.rename(path,
new_path)); before calling os.rename in the block that handles .yml files (the
variables path, new_path and the renamed list), add an explicit check like if
new_path.exists(): handle it (raise an error or skip and log) to prevent
overwriting on POSIX and to ensure consistent cross-platform behavior; only call
os.rename(path, new_path) and append to renamed if the destination does not
already exist.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: c8bd9276-b5d7-468e-962f-4cc5f125fc6c

📥 Commits

Reviewing files that changed from the base of the PR and between b6c6ec3 and 8e7ddb9.

📒 Files selected for processing (8)
  • .pre-commit-config.yaml
  • modelopt_recipes/general/ptq/fp8_default-fp8_kv.yaml
  • modelopt_recipes/general/ptq/nvfp4_default-fp8_kv.yaml
  • modelopt_recipes/general/ptq/nvfp4_experts_only-fp8_kv.yaml
  • modelopt_recipes/general/ptq/nvfp4_mlp_only-fp8_kv.yaml
  • modelopt_recipes/general/ptq/nvfp4_omlp_only-fp8_kv.yaml
  • tests/unit/recipe/test_loader.py
  • tools/precommit/normalize_yaml_ext.py

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 14, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 76.64%. Comparing base (1619421) to head (73b58df).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1260   +/-   ##
=======================================
  Coverage   76.64%   76.64%           
=======================================
  Files         355      355           
  Lines       41045    41045           
=======================================
  Hits        31460    31460           
  Misses       9585     9585           
Flag Coverage Δ
unit 55.71% <ø> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@shengliangxu shengliangxu requested a review from h-guo18 April 14, 2026 18:42
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
tools/precommit/normalize_yaml_ext.py (1)

34-57: Avoid partial renames when collisions exist.

Current flow can rename some files and still fail due to collisions, leaving a mixed working tree state. Prefer validating all candidates first, then applying renames only if there are no collisions.

Proposed refactor (all-or-nothing rename pass)
 def main() -> int:
     """Rename .yml files to .yaml, exit 1 if any were renamed."""
-    renamed: list[tuple[Path, Path]] = []
+    planned: list[tuple[Path, Path]] = []
     collisions: list[tuple[Path, Path]] = []
     for f in sys.argv[1:]:
         path = Path(f)
         if path.suffix == ".yml" and path.is_file():
             new_path = path.with_suffix(".yaml")
             if new_path.exists():
                 collisions.append((path, new_path))
                 continue
-            os.rename(path, new_path)
-            renamed.append((path, new_path))
+            planned.append((path, new_path))
 
     if collisions:
         for old, new in collisions:
             print(f"ERROR: Cannot rename {old} -> {new} (destination already exists)")
         return 1
 
+    renamed: list[tuple[Path, Path]] = []
+    for old, new in planned:
+        os.rename(old, new)
+        renamed.append((old, new))
+
     if renamed:
         for old, new in renamed:
             print(f"Renamed: {old} -> {new}")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tools/precommit/normalize_yaml_ext.py` around lines 34 - 57, The current loop
in normalize_yaml_ext.py performs renames as it iterates which can leave a
partially-renamed working tree if collisions are later detected; change the
logic in the main block that iterates over sys.argv[1:] to first collect all
candidate renames (map Path -> new_path) and detect collisions/new_path
existence using the same checks used for collisions, and only if collisions is
empty perform all os.rename operations (populating renamed afterwards); keep the
existing prints and return codes but ensure no os.rename is called until after
the preflight collision check so the rename is all-or-nothing.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tools/precommit/normalize_yaml_ext.py`:
- Around line 34-57: The current loop in normalize_yaml_ext.py performs renames
as it iterates which can leave a partially-renamed working tree if collisions
are later detected; change the logic in the main block that iterates over
sys.argv[1:] to first collect all candidate renames (map Path -> new_path) and
detect collisions/new_path existence using the same checks used for collisions,
and only if collisions is empty perform all os.rename operations (populating
renamed afterwards); keep the existing prints and return codes but ensure no
os.rename is called until after the preflight collision check so the rename is
all-or-nothing.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: d218306f-b097-432d-84ed-72faa57a9280

📥 Commits

Reviewing files that changed from the base of the PR and between 5f028d0 and dcc0787.

📒 Files selected for processing (2)
  • modelopt_recipes/general/ptq/nvfp4_default-none_kv_gptq.yaml
  • tools/precommit/normalize_yaml_ext.py

both file extensions are valid, but for files that are completely under
our control, might just normalize it to a single extension: .yaml. The
.yaml extension seems to be preferred by the yaml spec.

Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
@shengliangxu shengliangxu force-pushed the shengliangx/normalize-yaml-ext branch from 0d33159 to dce64ac Compare April 14, 2026 22:28
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tools/precommit/normalize_yaml_ext.py`:
- Around line 34-57: Scan all paths from sys.argv[1:] in two phases: first build
lists of planned renames by computing new_path = path.with_suffix(".yaml") and
detect collisions (if new_path.exists()) into collisions without performing any
os.rename, then in the second phase perform os.rename only for non-colliding
entries and append them to renamed; after that always print any Renamed: lines
and the restage guidance (and also print collision error lines) before returning
a non-zero exit code if collisions or renamed exist. This keeps the variables
collisions, renamed, new_path, os.rename and the original loop structure but
separates detection from mutation so partial renames are reported and collisions
are shown.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 50dcb3d8-5610-406d-9e3c-a5ee26ddbf20

📥 Commits

Reviewing files that changed from the base of the PR and between dcc0787 and dce64ac.

📒 Files selected for processing (9)
  • .pre-commit-config.yaml
  • modelopt_recipes/general/ptq/fp8_default-fp8_kv.yaml
  • modelopt_recipes/general/ptq/nvfp4_default-fp8_kv.yaml
  • modelopt_recipes/general/ptq/nvfp4_default-none_kv_gptq.yaml
  • modelopt_recipes/general/ptq/nvfp4_experts_only-fp8_kv.yaml
  • modelopt_recipes/general/ptq/nvfp4_mlp_only-fp8_kv.yaml
  • modelopt_recipes/general/ptq/nvfp4_omlp_only-fp8_kv.yaml
  • tests/unit/recipe/test_loader.py
  • tools/precommit/normalize_yaml_ext.py
✅ Files skipped from review due to trivial changes (2)
  • .pre-commit-config.yaml
  • tests/unit/recipe/test_loader.py

@shengliangxu shengliangxu merged commit c9b1155 into main Apr 15, 2026
37 checks passed
@shengliangxu shengliangxu deleted the shengliangx/normalize-yaml-ext branch April 15, 2026 00:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants